#include "TrabalhoFinal.h"
#include <iostream> 


inline const int RecalcularLarguraAltura(const int currentValue, const int newProportionalValue,const int oldProportionalValue)
{
	return static_cast<int>(0.5 + ((double)newProportionalValue/oldProportionalValue) * currentValue);
}

cv::Mat ReescalarCaractere(const cv::Mat &img,int width,int height)
{
	int newWidth = 0;
	int newHeight = 0;
	cv::Mat imOut;
	if(width > 0 && height > 0)
	{
		newWidth = width;
		newHeight = height;
	}
	else if(width > 0)
	{
		newWidth = width;
		newHeight = ::RecalcularLarguraAltura(img.rows,width,img.cols);;
	}
	else if(height > 0)
	{
		newWidth = ::RecalcularLarguraAltura(img.cols,height,img.rows);
		newHeight = height;	
	}
	int maxWidth = img.rows;
	int maxHeight = img.cols;
	if(newHeight >maxHeight)
	{
		newHeight = maxHeight;
	}
	if(newWidth >maxWidth)
	{
		newWidth = maxWidth;
	}

	if(newWidth > 0 && newHeight > 0)
	{
		//newCharImg.create(newWidth,newHeight);
		
		cv::resize(img,imOut,cv::Size(newWidth,newHeight),0,0,0);

		//charImg = newCharImg;
	}

	return imOut ;
}



std::string ReconheceCaracteres(const cv::Mat&img,const std::vector<cv::Rect>&blobs,TemplateMatching::Templates & templates)
{
	
	cv::Size maxTemplateSize = templates.GetMaximumTemplateSize();
	
	if(maxTemplateSize.width%2==0)
		maxTemplateSize.width = maxTemplateSize.width +1;
	if(maxTemplateSize.height%2==0)
		maxTemplateSize.height = maxTemplateSize.height +1;

	cv::Mat resultImg(maxTemplateSize.width,maxTemplateSize.height,0);
	
	typedef std::map<int,double>  MapaRespostas;	
	typedef std::pair<int,double>  ParIndiceResposta;
	typedef std::vector<ParIndiceResposta>  VetorRespostas;

	std::string resposta = "";
	cv::Mat imChar(maxTemplateSize,0);

	cv::Rect curRect;
	int templateId= 0;
	try
	{
		for(size_t i = 0 ; i < blobs.size(); i++)
		{
			curRect = blobs[i];
			VetorRespostas respostas;
			cv::Rect charRoi (blobs[i].x-maxTemplateSize.width/2,blobs[i].y-maxTemplateSize.height/2,maxTemplateSize.width,maxTemplateSize.height);

			resultImg = cv::Mat::zeros(maxTemplateSize.width,maxTemplateSize.height,0);
		
			cv::Rect imCharRect((imChar.cols - blobs[i].width)/2,(imChar.rows-blobs[i].height)/2,blobs[i].width,blobs[i].height);
			imChar = 0;
			img(blobs[i]).copyTo(imChar(imCharRect) );
	//		cv::imshow("r",imChar);
		//	cv::waitKey();
			for(size_t ti = 0 ; ti < templates.GetNumberOfTemplates();ti++)
			{		
				templateId = ti;
				auto templateImg = templates.GetImage(ti);			
			
				//cv::imwrite("d:\\template0.bmp",templateImg);
			
				if(blobs[i].height > 3 )
				{					
				//	templateImg = ::ReescalarCaractere(templateImg,-1,blobs[i].height);
				}

				
				//cv::imwrite("d:\\template1.bmp",templateImg);

				//std::cout <<"match "+std::to_string(long long(i)) + " " +std::to_string(long long(ti)) << std::endl;
				cv::matchTemplate(imChar,templateImg,resultImg,CV_TM_CCOEFF);

				//cv::imwrite("d:\\"+ std::to_string((long long)ti)+".bmp",resultImg);
				double min,max;
				//std::cout <<"minmax";
				cv::minMaxLoc(resultImg,&min,&max);

				respostas.push_back(ParIndiceResposta(ti,max));
			
			}
		
			std::sort(respostas.begin(),respostas.end(),[](const ParIndiceResposta&p1,const ParIndiceResposta&p2){return p1.second > p2.second;});

			resposta += templates.GetChar(respostas.begin()->first);
		}
	}
	catch(std::exception &ex)
	{
		throw std::exception("erro durante reconhecimento");
	}
	return resposta;
}
